package cn.stylefeng.guns.modular.gridsystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.context.login.LoginContextHolder;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.factory.PageFactory;
import cn.stylefeng.guns.modular.gridsystem.constants.SystemConstant;
import cn.stylefeng.guns.modular.gridsystem.entity.BizGateway;
import cn.stylefeng.guns.modular.gridsystem.entity.SoundCard;
import cn.stylefeng.guns.modular.gridsystem.enums.SoundCardExceptionEnum;
import cn.stylefeng.guns.modular.gridsystem.enums.SystemParamExceptionEnum;
import cn.stylefeng.guns.modular.gridsystem.mapper.BizGatewayMapper;
import cn.stylefeng.guns.modular.gridsystem.mapper.SoundCardMapper;
import cn.stylefeng.guns.modular.gridsystem.model.param.SoundCardParam;
import cn.stylefeng.guns.modular.gridsystem.model.result.SoundCardResult;
import cn.stylefeng.guns.modular.gridsystem.service.SoundCardService;
import cn.stylefeng.guns.modular.gridsystem.utils.OptionalBean;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 声卡业务实现
 *
 * @author zxw 2022/12/15 11:29
 */
@Slf4j
@Service
public class SoundCardServiceImpl extends ServiceImpl<SoundCardMapper, SoundCard> implements SoundCardService {

    @Resource
    private BizGatewayMapper gatewayMapper;

    /**
     * 分页查询声卡
     *
     * @param param cardName 声卡名称
     *              code 声卡名称
     *              distinguishCode 声卡识别名称
     * @return Page<SoundCardResult>
     * @author 乔李莱莱
     * @date 2023/10/17
     */
    @Override
    public Page<SoundCardResult> page(SoundCardParam param) {
        return baseMapper.page(PageFactory.defaultPage(), param);
    }

    /**
     * 带查询条件 查询所有声卡
     *
     * @param param cardName 声卡名称
     *              code 声卡名称
     *              distinguishCode 声卡识别名称
     * @return ist<SoundCardResult>
     * @author 乔李莱莱
     * @date 2023/10/17
     */
    @Override
    public List<SoundCardResult> list(SoundCardParam param) {
        if (ObjectUtil.isEmpty(param)) {
            param = new SoundCardParam();
        }
        LambdaQueryWrapper<SoundCard> wrapper = new LambdaQueryWrapper<SoundCard>()
                .like(ObjectUtil.isNotEmpty(param.getCardName()), SoundCard::getCardName, param.getCardName())
                .like(ObjectUtil.isNotEmpty(param.getCode()), SoundCard::getCode, param.getCode())
                .like(ObjectUtil.isNotEmpty(param.getDistinguishCode()), SoundCard::getDistinguishCode, param.getCode());
        return list(wrapper).stream()
                .map(item -> BeanUtil.toBean(item, SoundCardResult.class))
                .collect(Collectors.toList());
    }

    /**
     * 添加声卡
     *
     * @param param code 编码
     *              cardName 声卡名称
     *              distinguishCode 声卡识别名称
     *              vocalTractNumber 声道数量
     * @author 乔李莱莱
     * @date 2023/10/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SoundCardParam param) {
        // 1、检查编码是否唯一
        if (count(new LambdaUpdateWrapper<SoundCard>().eq(SoundCard::getCode, param.getCode())) > 0) {
            throw new ServiceException(SoundCardExceptionEnum.SAME_CODE_EXIST);
        }
        // 2、检查名称是否唯一
        if (count(new LambdaUpdateWrapper<SoundCard>().eq(SoundCard::getCardName, param.getCardName())) > 0) {
            throw new ServiceException(SoundCardExceptionEnum.SAME_NAME_EXIST);
        }
        SoundCard soundCard = new SoundCard();
        BeanUtil.copyProperties(param, soundCard);
        soundCard.setCreateUser(LoginContextHolder.me().getSysLoginUser().getId());
        soundCard.setCreateTime(new Date());
        save(soundCard);
    }

    /**
     * 编辑声卡信息
     *
     * @param param code 编码
     *              cardName 声卡名称
     *              distinguishCode 声卡识别名称
     *              vocalTractNumber 声道数量
     * @author 乔李莱莱
     * @date 2023/10/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SoundCardParam param) {
        OptionalBean.ofNullable(param).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        SoundCard soundCard = queryAndValid(param.getId());
        // 1、检查名称是否唯一
        LambdaQueryWrapper<SoundCard> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SoundCard::getCardName, param.getCardName()).ne(SoundCard::getId, soundCard.getId());
        int countSoundCard = count(lambdaQueryWrapper);
        if (countSoundCard > SystemConstant.NUM_0) {
            throw new ServiceException(SoundCardExceptionEnum.SAME_NAME_EXIST);
        }
        BeanUtil.copyProperties(param, soundCard);
        soundCard.setUpdateUser(LoginContextHolder.me().getSysLoginUser().getId());
        soundCard.setUpdateTime(new Date());
        // 修改数据
        updateById(soundCard);

    }

    /**
     * 删除声卡
     *
     * @param param id 主键id
     * @author 乔李莱莱
     * @date 2023/10/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(SoundCardParam param) {
        //入参判空
        OptionalBean.ofNullable(param).orElseThrow(() -> new ServiceException(SystemParamExceptionEnum.PARAM_NULL_ERROR));
        SoundCard soundCard = queryAndValid(param.getId());
        // 1、如果有网关关联到这个声卡，则不允许进行删除操作
        LambdaQueryWrapper<BizGateway> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BizGateway::getSoundCardId, soundCard.getId());
        int bizGatewayCount = gatewayMapper.selectCount(lambdaQueryWrapper);
        if (bizGatewayCount > SystemConstant.NUM_0) {
            throw new ServiceException(SoundCardExceptionEnum.GATEWAY_ASSOCIATED_NOT_ALLOWED_DELETE);
        }
        // 2、删除数据
        removeById(queryAndValid(param.getId()));

    }

    /**
     * 根据主键查询声卡
     *
     * @param id 主键id
     * @return SoundCard 返回声卡
     * @author 乔李莱莱
     * @date 2023/10/17
     */
    private SoundCard queryAndValid(Long id) {
        OptionalBean.ofStr(id);
        SoundCard soundCard = getById(id);
        OptionalBean.ofNullable(soundCard).orElseThrow(() -> new ServiceException(SoundCardExceptionEnum.NOT_EXIST));
        return soundCard;
    }

}
